class mitt {
    constructor() {
        this.listens =new Map()
    }
    guid(){
        return 'xxxxxxxx_xxxx_4xxx_yxxx_xxxxxxxx'.replace(/[xy]/g, function (c) {
          let r = Math.random() * 16 | 0,v = c == 'x' ? r : (r & 0x3 | 0x8);
          return v.toString(16);
        });
    }
    //监听一个事件返回该事件的guid 输入uid为监听组件的uid
    //如果是最底层的组件 不调用emit的话uid可以为空
    //如果不是最底层的组件 调用emit的话uid需要填写this?.$?.uid
    on(type,handler,uid) {
        let array_handlers=this.listens.get(type);
        if(!array_handlers){
            array_handlers=[]
        }
        let id=this.guid();
        array_handlers.push({
            id,
            uid,
            handler,
        })
        this.listens.set(type, array_handlers)
        return id
    }
    //清除一个事件，如果存在guid则只清除该事件的guid
    off(type,id) {
        if(id){
            let array_handlers=this.listens.get(type);
            if(array_handlers?.length>0){
                let index=array_handlers?.findIndex((val)=>{
                    return val?.id==id
                })
                if(index>=0){
                    array_handlers.splice(index,1)
                }
                if(array_handlers?.length==0){
                    this.listens.delete(type);
                }
                else{
                    this.listens.set(type, array_handlers)
                }
            }
        }
        else{
            this.listens.delete(type);
        }
    }
    //触发一个事件,event为传入参数,in_id为触发哪一个type事件  out_id为type_back的哪一个回调
    //如果有多个type的监听事件时,无法确定in_id为触发哪一个type事件，因此只触发第一个
    //同一组件的on emit是一对
    //如果是emit进去的时候 无法确定in_id为触发哪一个type事件 因此只触发第一个
    //如果是emit出来结果的时候 就触发uid的那一个事件
    //事件type
    //事件type参数
    //事件回调组件
    //事件itype传入传出参数 this?.$?.uid
    emit(type,event,uid,itype="in") {
        let array_handlers=this.listens.get(type);
        if(array_handlers?.length>0){
            if(itype=="in"){
                let first_array_handler=array_handlers[0];
                first_array_handler?.handler(uid,event)
            }
            else if(itype=="all"){
                for (let i = 0; i < array_handlers?.length; i++) {
                    let one_array_handlers = array_handlers[i];
                    one_array_handlers?.handler(uid,event)
                }
            }
            else if(itype=="out"){
                let i=array_handlers?.findIndex((val)=>{
                    return val?.uid==uid
                })
                if(i>=0){
                    array_handlers[i]?.handler(event)
                }
            }
        }
    }
    aemit(type,event,uid) {
        this.emit(type,event,uid,"all")
    }
    iemit(type,event,uid) {
        this.emit(type,event,uid,"in")
    }
    oemit(type,event,uid) {
        this.emit(type,event,uid,"out")
    }
}
export default mitt